package com.sxjh.controller.ny;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sxjh.annotation.UserLog;
import com.sxjh.common.*;
import com.sxjh.entity.BaseEntity;
import com.sxjh.entity.FactoryEntity;
import com.sxjh.entity.PlannedOrdersEntity;
import com.sxjh.entity.Task;
import com.sxjh.entity.param.PlannedOrderAddParam;
import com.sxjh.entity.param.PlannedOrderListParam;
import com.sxjh.entity.param.PlannedOrderStatusParam;
import com.sxjh.service.FactoryService;
import com.sxjh.service.PlannedOrdersService;
import com.sxjh.service.TaskService;
import com.sxjh.service.UserService;
import com.sxjh.uitl.ExcelUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.compress.utils.Lists;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 内部倒运-计划单表 前端控制器
 * </p>
 *
 * @author guanxy
 * @since 2023-05-31
 */
@Slf4j
@Api(tags = "计划单表")
@RestController
@RequestMapping("/plannedOrders")
public class PlannedOrdersController extends BaseController {


    @Autowired
    private PlannedOrdersService plannedOrdersService;

    @Autowired
    private HttpServletRequest request;

    @Autowired
    private TaskService taskService;

    @Autowired
    HttpServletResponse response;

    @Autowired
    private ExcelUtils excelUtils;

    @Autowired
    private UserService userService;

    @Autowired
    private FactoryService factoryService;

    @ApiOperation("分页列表")
    @GetMapping(value = "/planned.list")
    public Result<ZPage<PlannedOrderListParam>> list(PlannedOrderListParam param) {
        IPage iPage = new Page(param.getCurrent(), param.getSize());
        if (param.getSize() == -1) {
            iPage.setSize(Constant.maxSize);
        }
        Integer id = getUserInfo(request);
        //根据用户id获取所有角色
        Set<String> roleIds = userService.roles(id);
        if (CollUtil.isEmpty(roleIds)) {
            return Result.ok(null);
        }

        //查询所有的工厂配置
        List<FactoryEntity> factoryList = factoryService.list();
        if (CollUtil.isNotEmpty(factoryList)) {
            List<Integer> upFactoryIdList = Lists.newArrayList();
            roleIds.forEach(r -> {
                //用户所属的角色是否在工厂配置中
                List<Integer> factoryIdList = factoryList.stream().filter(f -> {
                    String roleId = f.getRoleId();
                    if (StrUtil.isBlank(roleId)) return false;
                    List<String> roleId1s = Arrays.asList(roleId.split(","));
                    return roleId1s.contains(r);
                }).map(BaseEntity::getId).distinct().collect(Collectors.toList());
                if (CollUtil.isNotEmpty(factoryIdList)) {
                    upFactoryIdList.addAll(factoryIdList);
                }
            });
            if (CollUtil.isNotEmpty(upFactoryIdList)) {
                //去重
                Set<Integer> set = new HashSet<Integer>(upFactoryIdList);
                //log.info("====计划单分页查询用户id:{},,,角色id:{},,,工厂id:{}", id, JSONUtil.toJsonStr(roleIds), JSONUtil.toJsonStr(set));
                param.setUpFactoryIdList(set);
            }
        }
        param.setStatusList(ListUtil.toList(3));
        IPage<PlannedOrderListParam> aPage = plannedOrdersService.queryPage(iPage, param);
        ZPage<PlannedOrderListParam> zPage = copyPage(aPage, PlannedOrderListParam::new);
        return Result.ok(zPage);
    }

    @ApiOperation("查询")
    @GetMapping(value = "/{id}")
    public Result<PlannedOrderListParam> getById(@PathVariable("id") Integer id) {
        PlannedOrderListParam param = new PlannedOrderListParam();
        param.setId(id);
        IPage<PlannedOrderListParam> aPage = plannedOrdersService.queryPage(new Page<>(1, 10), param);
        if (aPage != null && CollUtil.isNotEmpty(aPage.getRecords())) {
            return Result.ok(aPage.getRecords().get(0));
        }
        return Result.err("数据不存在");
    }

    @ApiOperation("生成计划单")
    @PostMapping(value = "/add")
    @UserLog(desc = "内部倒运-生成计划单", roleCode = "nbdy.plannedOrders.add")
    public Result<Object> create(@RequestBody PlannedOrderAddParam params) {
        String orderNo = "JHD" + DateUtil.format(DateUtil.date(), "yyyyMMddHHmmssSSS") + RandomUtil.randomNumbers(4);
        PlannedOrdersEntity params1 = BeanUtil.copyProperties(params, PlannedOrdersEntity.class);
        params1.setOrderNo(orderNo);
        plannedOrdersService.save(params1);
        return Result.ok(HttpStatus.OK);
    }

    @ApiOperation("删除")
    @GetMapping(value = "/delete/{id}")
    @UserLog(desc = "内部倒运-删除计划单", roleCode = "nbdy.plannedOrders.del")
    public Result<Object> delete(@PathVariable("id") String id) {
        LambdaQueryWrapper<Task> query = new LambdaQueryWrapper<>();
        query.eq(Task::getPlannedOrderId, id);
        query.in(Task::getStatus, ListUtil.of(1, 2, 3, 4));
        int count = taskService.count(query);
        if (count > 0) {
            return Result.err("该计划单下有派车单，无法删除");
        }
        plannedOrdersService.removeById(id);
        return Result.ok(HttpStatus.OK);
    }

    @ApiOperation("修改")
    @PostMapping(value = "/update")
    @UserLog(desc = "内部倒运-修改计划单", roleCode = "nbdy.plannedOrders.update")
    public Result<Object> delete(@RequestBody PlannedOrderAddParam params) {
        PlannedOrdersEntity params1 = BeanUtil.copyProperties(params, PlannedOrdersEntity.class);
        plannedOrdersService.updateById(params1);
        return Result.ok(HttpStatus.OK);
    }

    @ApiOperation("计划单关闭")
    @GetMapping(value = "/updateStatus")
    @UserLog(desc = "内部倒运-关闭计划单", roleCode = "nbdy.plannedOrders.close")
    public Result<Object> updateStatus(PlannedOrderStatusParam param) throws ResultException {
        if (param.getClose() == null) {
            throw new ResultException("请选择操作项");
        }
        PlannedOrdersEntity plannedOrdersEntity = plannedOrdersService.getById(param.getId());
        if (Objects.isNull(plannedOrdersEntity)) {
            throw new ResultException("计划单不存在");
        }
        if (param.getClose() != null) {
            plannedOrdersEntity.setClose(param.getClose());
        }
        LambdaQueryWrapper<Task> query = new LambdaQueryWrapper<>();
        query.eq(Task::getPlannedOrderId, param.getId());
        query.in(Task::getStatus, ListUtil.of(2, 3, 4));
        int count = taskService.count(query);
        if (count > 0) {
            return Result.err("已有派车单在执行");
        }
        plannedOrdersService.updateById(plannedOrdersEntity);
        return Result.ok(HttpStatus.OK);
    }

    @ApiOperation("计划单导出")
    @GetMapping(value = "/planned-export")
    public void export(PlannedOrderListParam param) {
        IPage iPage = new Page(param.getCurrent(), param.getSize());
        if (param.getSize() == -1) {
            iPage.setSize(Constant.maxSize);
        }
        IPage<PlannedOrderListParam> aPage = plannedOrdersService.queryPage(iPage, param);
        Set<String> includeColumnFiledNames = new HashSet<>();
        includeColumnFiledNames.add("title");
        includeColumnFiledNames.add("orderNo");
        includeColumnFiledNames.add("materialName");
        includeColumnFiledNames.add("startDate");
        includeColumnFiledNames.add("endDate");
        includeColumnFiledNames.add("locationUpName");
        includeColumnFiledNames.add("locationDownName");
        includeColumnFiledNames.add("createdAt");
        includeColumnFiledNames.add("updatedAt");
        includeColumnFiledNames.add("total");
        includeColumnFiledNames.add("completeTotal");
        includeColumnFiledNames.add("locationUpFactoryName");
        includeColumnFiledNames.add("locationUpWorkshopName");
        includeColumnFiledNames.add("locationDownFactoryName");
        includeColumnFiledNames.add("locationDownWorkshopName");
        String fileName = "计划单表" + DateUtil.format(DateUtil.date(), "yyyyMMddHHmm");
        excelUtils.downLoadFromWeb(response, fileName, includeColumnFiledNames, aPage.getRecords(),
                "计划单表", PlannedOrderListParam.class);
    }

}
